package fem2;

/**
 * The clock to synchronise all aspect during computation
 * 
 * @author hbui
 * 
 */
public class Clock {

	private static Clock instance = new Clock();
	private static int Nt = 1;
	private static int step = 0;
	private static double T = 1;
	private double lambda = Double.NaN;

	private Clock() {
	}

	/**
	 * Get the instance of Clock singleton
	 * 
	 * @return the Singleton instance
	 */
	public static Clock getInstance() {
		return instance;
	}

	/**
	 * Set the number of steps and reset the clock
	 * 
	 * @param Nt
	 *            number of steps
	 */
	public void setNt(int Nt) {
		this.reset();
		Clock.Nt = Nt;
	}

	/**
	 * Get the number of steps
	 */
	public int getNt() {
		return Clock.Nt;
	}

	/**
	 * Set the time scale
	 * 
	 * @param T
	 */
	public void setTimeScale(double T) {
		Clock.T = T;
	}

	/**
	 * tick the clock to 1 increment
	 */
	public void tick() {
		if (Clock.step < Nt) {
			Clock.step++;
		}
	}

	/**
	 * reset the clock
	 */
	public void reset() {
		Clock.step = 0;
		this.lambda = Double.NaN;
	}

	/**
	 * Get the delta time w.r.t time scale
	 * 
	 * @return
	 */
	public double getTimeDelta() {
		return Clock.T / Clock.Nt;
	}

	/**
	 * Get the time scale
	 * 
	 * @return
	 */
	public double getTimeScale() {
		return Clock.T;
	}

	/**
	 * Get current reference analysis time. By convention, clock reference
	 * analysis time start from 0 and go to 1. After each tick, clock time
	 * increment by 1/Clock.Nt
	 * 
	 * @return
	 */
	public double getAnalysisTime() {
		return (double) (Clock.step) / Clock.Nt;
	}

	/**
	 * Get the lambda associated with the current time
	 * 
	 * @return
	 */
	public double getLambda() {
		if (!Double.isNaN(this.lambda)) {
			return this.lambda;
		}
		return this.getAnalysisTime() / this.getEndTime();
	}

	/**
	 * Get end time
	 * 
	 * @return
	 */
	public double getEndTime() {
		return 1.0;
	}

}
